﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Reflection;

namespace System {
    [DebuggerDisplay("Entity:{GetType().Name}, ID:{ID}, Name:{Name}, OrderBy:{OrderBy}")]
    public abstract class Entity:Entity<string>, IEntity {
        public Entity() {
            ID = UUIDUtils.Fid;
        }
    }
    [DebuggerDisplay("Entity:{GetType().Name}, ID:{ID}, Name:{Name}")]
    public abstract class Entity<TPrimaryKey>:IEntity<TPrimaryKey> {
        public Entity() {
            OrderBy = 0;
            AddTime = DateTime.Now;
        }
        /// <summary>
        /// 唯一标识
        /// </summary>
        [Description("唯一标识")]
        [Key]
        [Display(Name = "唯一标识")]
        public virtual TPrimaryKey ID { get; set; }
        /// <summary>
        /// 排序
        /// </summary>
        [Description("排序")]
        [Display(Name = "排序")]
        public virtual int OrderBy { get; set; }
        /// <summary>
        /// 添加时间
        /// </summary>
        [Description("添加时间")]
        [Display(Name = "添加时间")]
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm:ss}",ApplyFormatInEditMode = true)]
        public virtual DateTime AddTime { get; set; }
        public void Create() {
            if(ID == null) ID = default(TPrimaryKey);
            var entity = this as TreeEntity;
            if(entity != null) {
                if(string.IsNullOrWhiteSpace(entity.ParentID)) {
                    entity.ParentID = Guid.Empty.ToString();
                }
            }
            var creationAudited = this as ICreationAudited;
            if(creationAudited != null) {
                try {
                    if(string.IsNullOrWhiteSpace(creationAudited.AddUserID)) {
                        var accountId = HttpContextCore.Current?.User?.FindFirst(ClaimsName.UserID);
                        if(accountId != null && accountId.Value.NotNull()) {
                            creationAudited.AddUserID = accountId.Value.Trim();
                        }
                    }
                } catch { }
            }
            var tenant = this as ITenant;
            if(tenant != null) {
                try {
                    if(string.IsNullOrWhiteSpace(tenant.TenantId)) {
                        var tenantId = HttpContextCore.Current?.User?.FindFirst(ClaimsName.TenantId);
                        if(tenantId != null && tenantId.Value.NotNull()) {
                            tenant.TenantId = tenantId.Value.Trim();
                        }
                    }
                } catch { }
            }
        }
        public void Modify() {
            var creationAudited = this as IModificationAudited;
            if(creationAudited != null) {
                try {
                    var accountId = HttpContextCore.Current?.User?.FindFirst(ClaimsName.UserID);
                    if(accountId != null && accountId.Value.NotNull()) {
                        creationAudited.EditUserID = accountId.Value.Trim();
                    }
                } catch { }
                creationAudited.EditTime = DateTime.Now;
            }
        }
        public void Remove() {
            var entity = this as ISoftDelete;
            if(entity != null) {
                try {
                    var accountId = HttpContextCore.Current?.User?.FindFirst(ClaimsName.UserID);
                    if(accountId != null && accountId.Value.NotNull()) {
                        entity.DeleteUserID = accountId.Value.Trim();
                    }
                } catch { }
                entity.IsDelete = 1;
                entity.DeleteTime = DateTime.Now;
            }
        }


        public static bool operator ==(Entity<TPrimaryKey> left,Entity<TPrimaryKey> right) {
            if(Object.Equals(left,null))
                return (Object.Equals(right,null)) ? true : false;
            else
                return left.Equals(right);
        }
        public static bool operator !=(Entity<TPrimaryKey> left,Entity<TPrimaryKey> right) {
            return !(left == right);
        }
        public override string ToString() {
            return $"[{GetType().Name} {ID}]";
        }
    }
    /// <summary>
    /// 树形
    /// </summary>
    [Serializable]
    [DebuggerDisplay("Entity:{GetType().Name}, ID:{ID}, Name:{Name}")]
    public abstract class TreeEntity:TreeEntity<string> {
        public TreeEntity() {
            ParentID = Guid.Empty.ToString();
        }
    }
    /// <summary>
    /// 树形
    /// </summary>
    [DebuggerDisplay("Entity:{GetType().Name}, ID:{ID}, Name:{Name}")]
    public abstract partial class TreeEntity<TPrimaryKey>:Entity {
        public TreeEntity() {

        }
        /// <summary>
        /// 名称
        /// </summary>
        [Description("名称")]
        public virtual string Name { get; set; }
        /// <summary>
        /// 上一级
        /// </summary>
        [Description("上一级")]
        [Display(Name = "上一级")]
        public TPrimaryKey ParentID { get; set; }
    }
}
